// krcParser.ts
import fs from "fs";
import zlib from "zlib";
import { promisify } from "util";

const gunzip = promisify(zlib.gunzip);
const inflate = promisify(zlib.inflate);

// 定义歌词行接口
export interface LyricLine {
  time: number; // 开始时间（毫秒）
  duration: number; // 持续时间（毫秒）
  content: string; // 歌词内容
}

// 解析KRC文件
export async function parseKrcFile(filePath: string): Promise<LyricLine[]> {
  try {
    // 读取KRC文件
    const data = await fs.promises.readFile(filePath);

    // 检查文件头（KRC文件通常有4字节的魔数）
    const magic = data.slice(0, 4);
    if (magic.toString() !== "krc1") {
      throw new Error("Invalid KRC file: magic number mismatch");
    }

    // 获取加密密钥（KRC文件第4-8字节是密钥）
    const keyBytes = data.slice(4, 8);

    // 解密数据（KRC文件从第8字节开始是加密数据）
    const encryptedData = data.slice(8);
    const decryptedData = Buffer.alloc(encryptedData.length);

    // 使用密钥进行异或解密
    for (let i = 0; i < encryptedData.length; i++) {
      decryptedData[i] = encryptedData[i] ^ keyBytes[i % 4];
    }

    // 尝试使用gzip解压缩
    let decompressedData;
    try {
      decompressedData = await gunzip(decryptedData);
    } catch (gzipError) {
      const errorMsg =
        gzipError instanceof Error ? gzipError.message : String(gzipError);
      console.warn(`gzip解压缩失败，尝试zlib解压缩: ${errorMsg}`);
      // 如果gzip失败，尝试使用zlib解压缩
      decompressedData = await inflate(decryptedData);
    }

    // 将解压后的Buffer转换为字符串（UTF-8编码）
    const lyricText = decompressedData.toString("utf8");

    // 按行分割歌词文本
    const lines = lyricText.split("\n");

    // 解析每一行歌词
    const lyricLines: LyricLine[] = [];
    for (const line of lines) {
      if (!line.trim()) continue; // 跳过空行

      // 解析行：格式为 [开始时间,持续时间]歌词内容
      // 例如：[0,1000]歌词
      const match = line.match(/^\[(\d+),(\d+)\](.*)$/);
      if (match) {
        const startTime = parseInt(match[1], 10);
        const duration = parseInt(match[2], 10);
        const content = match[3].trim();

        lyricLines.push({
          time: startTime,
          duration,
          content,
        });
      }
    }

    return lyricLines;
  } catch (error) {
    console.error(`解析KRC文件失败: ${filePath}`, error);
    throw new Error("解析歌词失败");
  }
}
